package com.pai4j.message.subscription;

import com.pai4j.message.model.MessageContext;
import com.pai4j.message.model.SubscriptionConfig;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.function.BiPredicate;

/**
 * 订阅规则
 * 定义订阅匹配逻辑
 *
 * @author PAI4J Team
 * @date 2025-11-01
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SubscriptionRule {

    /**
     * 规则名称
     */
    private String ruleName;

    /**
     * 规则描述
     */
    private String description;

    /**
     * 优先级（数字越小优先级越高）
     */
    @Builder.Default
    private Integer priority = 10;

    /**
     * 是否启用
     */
    @Builder.Default
    private Boolean enabled = true;

    /**
     * 匹配器
     */
    private BiPredicate<MessageContext, SubscriptionConfig> matcher;

    /**
     * 判断消息是否匹配订阅配置
     */
    public boolean matches(MessageContext context, SubscriptionConfig config) {
        if (!enabled || context == null || config == null || !config.getEnabled()) {
            return false;
        }

        // 检查静默时段
        if (config.isInQuietPeriod()) {
            return false;
        }

        // 使用自定义匹配器
        if (matcher != null) {
            return matcher.test(context, config);
        }

        // 默认匹配逻辑
        return defaultMatch(context, config);
    }

    /**
     * 默认匹配逻辑
     */
    private boolean defaultMatch(MessageContext context, SubscriptionConfig config) {
        // 1. 检查消息类型
        if (context.getMessageDTO() != null) {
            String messageType = context.getMessageDTO().getClass().getSimpleName();
            if (!config.isSubscribedToMessageType(messageType)) {
                return false;
            }
        }

        // 2. 检查资源
        if (context.getResourceInfo() != null) {
            String resourceId = context.getResourceInfo().getResourceId();
            if (!config.isSubscribedToResource(resourceId)) {
                return false;
            }
        }

        // 3. 检查发送者
        if (context.getSenderId() != null) {
            if (!config.isSubscribedToUser(context.getSenderId())) {
                return false;
            }
        }

        return true;
    }

    /**
     * 创建消息类型订阅规则
     */
    public static SubscriptionRule createMessageTypeRule() {
        return SubscriptionRule.builder()
                .ruleName("message-type")
                .description("按消息类型订阅")
                .priority(1)
                .enabled(true)
                .matcher((context, config) -> {
                    if (context.getMessageDTO() == null) {
                        return false;
                    }
                    String messageType = context.getMessageDTO().getClass().getSimpleName();
                    return config.isSubscribedToMessageType(messageType);
                })
                .build();
    }

    /**
     * 创建资源订阅规则
     */
    public static SubscriptionRule createResourceRule() {
        return SubscriptionRule.builder()
                .ruleName("resource")
                .description("按资源订阅")
                .priority(2)
                .enabled(true)
                .matcher((context, config) -> {
                    if (context.getResourceInfo() == null) {
                        return false;
                    }
                    String resourceId = context.getResourceInfo().getResourceId();
                    return config.isSubscribedToResource(resourceId);
                })
                .build();
    }

    /**
     * 创建用户订阅规则
     */
    public static SubscriptionRule createUserRule() {
        return SubscriptionRule.builder()
                .ruleName("user")
                .description("按用户订阅")
                .priority(3)
                .enabled(true)
                .matcher((context, config) -> {
                    if (context.getSenderId() == null) {
                        return false;
                    }
                    return config.isSubscribedToUser(context.getSenderId());
                })
                .build();
    }
}

